package com.link2room.soundwave.facade.impl;

import com.greencloud.api.dto.RmtypeDateAvailDto;
import com.greencloud.api.entity.RmtypeAvail;
import com.greencloud.api.request.ListRoomAvailRequest;
import com.greencloud.api.request.RmtypeAvailRequest;
import com.greencloud.api.response.RmtypeAvailResponse;
import com.greencloud.api.response.RoomAvailResponse;
import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.param.base.BaseL2rParamDto;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.*;
import com.link2room.enums.exception.SoundwaveSysExceptionEnum;
import com.link2room.soundwave.entity.L2RIpms2Hotel;
import com.link2room.soundwave.entity.L2RIpms2Rmtype;
import com.link2room.soundwave.entity.GcRmtypeAvailSync;
import com.link2room.soundwave.exception.SoundwaveException;
import com.link2room.soundwave.constant.SoundwaveMnsConstant;
import com.link2room.soundwave.constant.SoundwaveTaskNameConstant;
import com.link2room.soundwave.dto.param.inside.PmsRoomAvailInsideParamDto;
import com.link2room.soundwave.dto.result.base.PmsRmtypeAvailDto;
import com.link2room.soundwave.util.GcPmsUtil;
import greencloud.ipms2.result.IPMS2RmtypeAvailSyncDto;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by sss on 2017/5/18.
 */
@Component("gcPmsRoomAvailHandlerFacadeService")
public class GcPmsRoomAvailHandlerFacadeServiceImpl extends AbstractPmsRoomAvailHandlerFacadeServiceImpl {
    @Resource
    private ICommonService commonService;

    @Override
    void syncPMSRoomAvail(PmsRoomAvailInsideParamDto pmsRoomAvailInsideParamDto) throws Exception {
        L2RIpms2Hotel queryIH = new L2RIpms2Hotel();
        queryIH.setLhotelGroupCode(pmsRoomAvailInsideParamDto.getLhotelGroupCode());
        queryIH.setIsHalt(DefaultValue.F);
        if(StringUtil.isNotBlank( pmsRoomAvailInsideParamDto.getLhotelCode() )){
            queryIH.setLhotelCode( pmsRoomAvailInsideParamDto.getLhotelCode());
        }
        Date now = new Date();

        QueryResult<L2RIpms2Hotel> l2RPmsHotelQueryResult= commonService.findAllEQ( L2RIpms2Hotel.class, queryIH);
        if(  null !=l2RPmsHotelQueryResult.getResultlist()&& l2RPmsHotelQueryResult.getResultlist().size()>0){
            Date arr= DateUtil.addDays( now, pmsRoomAvailInsideParamDto.getStartIndex() );
            Date dep=DateUtil.addDays( arr, pmsRoomAvailInsideParamDto.getDayStep() );
            String arrtime=DateUtil.getWebDateString(arr);
            String deptime=DateUtil.getWebDateString(dep);
            List<PmsRoomAvailInsideParamDto> pmsRoomAvailParamDtos=new ArrayList<>();
            if(l2RPmsHotelQueryResult.getResultlist()!=null&&l2RPmsHotelQueryResult.getResultlist().size()>0){
                for (L2RIpms2Hotel l2RIpms2Hotel1 : l2RPmsHotelQueryResult.getResultlist()) {
                    PmsRoomAvailInsideParamDto pmsRoomAvailParamDto = new PmsRoomAvailInsideParamDto();
                    pmsRoomAvailParamDto.setHotelId( l2RIpms2Hotel1.getHotelId() );
                    pmsRoomAvailParamDto.setHotelGroupId( l2RIpms2Hotel1.getHotelGroupId());
                    pmsRoomAvailParamDto.setArrtime(arrtime);
                    pmsRoomAvailParamDto.setDeptime(deptime);
                    pmsRoomAvailParamDto.setRmtypes("");
                    pmsRoomAvailParamDto.setLhotelGroupCode(l2RIpms2Hotel1.getLhotelGroupCode() );
                    pmsRoomAvailParamDto.setLhotelCode(l2RIpms2Hotel1.getLhotelCode() );
                    if(null==l2RIpms2Hotel1.getUnuseRmnum()){
                        pmsRoomAvailParamDto.setUnuseRmnum(0);
                    }else {
                        pmsRoomAvailParamDto.setUnuseRmnum(l2RIpms2Hotel1.getUnuseRmnum());
                    }
                    pmsRoomAvailParamDtos.add(pmsRoomAvailParamDto);
                }
                BatchUtil.beginBatchTask(SoundwaveMnsConstant.QUEUE_PMSROOMAVAIL,
                        SoundwaveTaskNameConstant.SAVE_PMS_ROOMAVAIL,
                        pmsRoomAvailParamDtos);
            }
        }
    }

    @Override
    void syncPMSHotelRoomAvail(PmsRoomAvailInsideParamDto pmsRoomAvailInsideParamDto) throws Exception {
        String lhotelGroupCode=pmsRoomAvailInsideParamDto.getLhotelGroupCode();
        String lhotelCode=pmsRoomAvailInsideParamDto.getLhotelCode();
        L2RIpms2Rmtype querylrmtype = new L2RIpms2Rmtype();
        querylrmtype.setLhotelGroupCode(lhotelGroupCode);
        querylrmtype.setLhotelCode( lhotelCode);
        QueryResult<L2RIpms2Rmtype> l2RIpms2RmtypeQueryResult = commonService.findAllEQ( L2RIpms2Rmtype.class,querylrmtype );
        Map<String ,String> rmtypeMap = new HashMap<>();
        String roomTypes = "";
        if(null!=l2RIpms2RmtypeQueryResult&& l2RIpms2RmtypeQueryResult.getResultlist().size()>0 ) {
            for (L2RIpms2Rmtype lir : l2RIpms2RmtypeQueryResult.getResultlist()) {
                rmtypeMap.put(lir.getLhotelCode() + DefaultValue.MARK + lir.getPmsRmtype(), lir.getL2RRmtype());
                roomTypes = roomTypes + lir.getPmsRmtype() + ",";
            }
            pmsRoomAvailInsideParamDto.setRmtypes(roomTypes);
            List<IPMS2RmtypeAvailSyncDto> pmsRmtypeAvailSyncDtos = this.getGcRoomAvail(pmsRoomAvailInsideParamDto);
            List<GcRmtypeAvailSync> gcRmtypeAvailSyncs =ClassConverUtil.copyPropertiesList(pmsRmtypeAvailSyncDtos,GcRmtypeAvailSync.class);
            L2RCondition l2RCondition = new L2RCondition();
            l2RCondition.setAndConditions(new ConditionDetail[]{
                    new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, lhotelGroupCode),
                    new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ, lhotelCode),
                    new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.occDate.toString(), CriteriaUtil.Operator.GTE, DateUtil.parseDateNewFormat(pmsRoomAvailInsideParamDto.getArrtime())),
                    new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.occDate.toString(), CriteriaUtil.Operator.LTE, DateUtil.parseDateNewFormat(pmsRoomAvailInsideParamDto.getDeptime()))
            });
            QueryResult<GcRmtypeAvailSync> pmsRmtypeAvailSyncResult = commonService.findAllByCondition(GcRmtypeAvailSync.class, l2RCondition);
            Iterator<GcRmtypeAvailSync> it = gcRmtypeAvailSyncs.iterator();
            List<GcRmtypeAvailSync> oldPmsRmtypeAvailList = pmsRmtypeAvailSyncResult.getResultlist();
            while (it.hasNext()) {
                GcRmtypeAvailSync gcRmtypeAvailSync = it.next();
                gcRmtypeAvailSync.setLhotelGroupCode(lhotelGroupCode);
                gcRmtypeAvailSync.setLhotelCode(lhotelCode);
                Integer saleNum= gcRmtypeAvailSync.getAvail()-pmsRoomAvailInsideParamDto.getUnuseRmnum();
                if(saleNum<0){
                    saleNum=0;
                }
                gcRmtypeAvailSync.setSaleNum(saleNum);
                gcRmtypeAvailSync.setL2RRmtype(rmtypeMap.get(gcRmtypeAvailSync.getLhotelCode() + DefaultValue.MARK + gcRmtypeAvailSync.getRmtype()));

                if (oldPmsRmtypeAvailList != null && oldPmsRmtypeAvailList.size() > 0) {
                    for (GcRmtypeAvailSync oldPmsRmtypeAvail : oldPmsRmtypeAvailList) {
                        if (oldPmsRmtypeAvail.getRmtype().equals(gcRmtypeAvailSync.getRmtype())
                                && DateUtil.format(oldPmsRmtypeAvail.getOccDate(), DateUtil.webFormat).equals(DateUtil.format(gcRmtypeAvailSync.getOccDate(), DateUtil.webFormat))) {
                            oldPmsRmtypeAvail.setSaleNum(gcRmtypeAvailSync.getSaleNum());
                            oldPmsRmtypeAvail.setAvail(gcRmtypeAvailSync.getAvail());
                            oldPmsRmtypeAvail.setRmtypeNum(gcRmtypeAvailSync.getRmtypeNum());
                            it.remove();
                            break;
                        }
                    }
                }
            }
            commonService.mergeList(oldPmsRmtypeAvailList);
            commonService.saveList(gcRmtypeAvailSyncs);
        }
        BatchUtil.doBatchTaskDone(pmsRoomAvailInsideParamDto.getTaskMainId(),
                pmsRoomAvailInsideParamDto.getTaskId(),
                pmsRoomAvailInsideParamDto.getIsBatch());
    }

    /**
     * 绿云查询房量抵离时间几天就有几天的查询量
     * @param pmsRoomAvailInsideParamDto
     * @return
     * @throws Exception
     */
    List<IPMS2RmtypeAvailSyncDto> getGcRoomAvail(PmsRoomAvailInsideParamDto pmsRoomAvailInsideParamDto) throws Exception {
        ListRoomAvailRequest listRoomAvailRequest = ListRoomAvailRequest.newInstance();
        listRoomAvailRequest.setHotelGroupId(pmsRoomAvailInsideParamDto.getHotelGroupId());
        listRoomAvailRequest.setHotelId(pmsRoomAvailInsideParamDto.getHotelId());
        listRoomAvailRequest.setArr(pmsRoomAvailInsideParamDto.getArrtime());
        listRoomAvailRequest.setDep(DateUtil.getNewFormatDateString(DateUtil.addDays(pmsRoomAvailInsideParamDto.getDep(),-1L)));
        listRoomAvailRequest.setRmtype(pmsRoomAvailInsideParamDto.getRmtypes());
        RoomAvailResponse resp = GcPmsUtil.getGcClient(pmsRoomAvailInsideParamDto.getLhotelGroupCode()).execute(listRoomAvailRequest);
        if(resp.getResultCode()<0){
            throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_AVAIL_ERROR,resp.getResultMsg());
        }else {
            List<RmtypeAvail> rmtypeAvails = resp.getResult();
            return ClassConverUtil.copyPropertiesList(rmtypeAvails, IPMS2RmtypeAvailSyncDto.class);
        }
    }


    @Override
    List<PmsRmtypeAvailDto> getPmsRoomAvailDirect(PmsRoomAvailInsideParamDto roomAvailInsideParamDto) throws Exception {

        L2RIpms2Hotel l2RIpms2Hotel = new L2RIpms2Hotel();
        l2RIpms2Hotel.setLhotelGroupCode(roomAvailInsideParamDto.getLhotelGroupCode());
        L2RAssert.stringBlank(roomAvailInsideParamDto.getLhotelCode(),"酒店代码为空");
        l2RIpms2Hotel.setLhotelCode( roomAvailInsideParamDto.getLhotelCode());

        l2RIpms2Hotel  = commonService.findOneEQ( L2RIpms2Hotel.class, l2RIpms2Hotel);
        if(l2RIpms2Hotel!=null){
            L2RIpms2Rmtype querylrmtype = new L2RIpms2Rmtype();
            querylrmtype.setLhotelGroupCode(roomAvailInsideParamDto.getLhotelGroupCode());
            querylrmtype.setLhotelCode( roomAvailInsideParamDto.getLhotelCode());
            querylrmtype.setL2RRmtype(roomAvailInsideParamDto.getL2RRmtypes());
            L2RIpms2Rmtype l2RIpms2Rmtype = commonService.findOneEQ( L2RIpms2Rmtype.class,querylrmtype );
            if(l2RIpms2Rmtype==null){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPINGRMTYPE_NOT_EXIT);
            }
            RmtypeAvailRequest request = RmtypeAvailRequest.newInstance();
            request.setHotelGroupId(l2RIpms2Hotel.getHotelGroupId());
            request.setHotelId(l2RIpms2Hotel.getHotelId().toString());
            request.setArr(roomAvailInsideParamDto.getArrtime());
            request.setDep(DateUtil.getNewFormatDateString(DateUtil.addDays(roomAvailInsideParamDto.getDep(),-1L)));
            request.setRmtype(l2RIpms2Rmtype.getPmsRmtype());
            request.setSalesChannel(roomAvailInsideParamDto.getSalesChannel());
            request.setRatecode(roomAvailInsideParamDto.getPmsRatecode());
            RmtypeAvailResponse resp = GcPmsUtil.getGcClient(roomAvailInsideParamDto.getLhotelGroupCode()).execute(request);
            if(resp.getResultCode()<0){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_AVAIL_ERROR,resp.getResultMsg());
            }else {
                List<RmtypeDateAvailDto> rmtypeAvails = resp.getResult();
                List<PmsRmtypeAvailDto> rmtypeAvailDirects=new ArrayList<>();
                PmsRmtypeAvailDto rmtypeAvailDirect;
                for(RmtypeDateAvailDto rmtypeAvail:rmtypeAvails){
                    rmtypeAvailDirect=ClassConverUtil.copyPropertiesToDto(rmtypeAvail,PmsRmtypeAvailDto.class,false);
                    rmtypeAvailDirect.setRsvDate(rmtypeAvail.getDate());
                    Integer saleNum=rmtypeAvailDirect.getAvail()-l2RIpms2Hotel.getUnuseRmnum();
                    if(saleNum<0){
                        saleNum=0;
                    }
                    rmtypeAvailDirect.setSaleNum(saleNum);
                    rmtypeAvailDirects.add(rmtypeAvailDirect);
                }
                return rmtypeAvailDirects;
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPINGHOTEL_NOT_EXIT);
        }

    }

    @Override
    void deletePmsRoomAvail(BaseL2rParamDto baseL2rParamDto) throws Exception {
        L2RCondition l2RCondition=new L2RCondition();
        l2RCondition.setAndConditions(
                new ConditionDetail[]{
                        new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, baseL2rParamDto.getLhotelGroupCode()),
                        new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.occDate.toString(), CriteriaUtil.Operator.LT, DateUtil.addDays(new Date(),-baseL2rParamDto.getDayStep()))
                }
        );
        commonService.deleteByCondition(GcRmtypeAvailSync.class,l2RCondition);
    }

    @Override
    QueryResult<PmsRmtypeAvailDto> getPmsRoomAvail(PmsRoomAvailInsideParamDto roomAvailInsideParamDto) throws Exception {
        List<String> l2rRmtypes = new ArrayList<>();
        if( roomAvailInsideParamDto.getL2RRmtypes()!=null&& roomAvailInsideParamDto.getL2RRmtypes().length()>0){
            String [] temp= roomAvailInsideParamDto.getL2RRmtypes().split(",");
            for ( String str : temp){
                l2rRmtypes.add( str);
            }
        }
        L2RCondition stockConfition=new L2RCondition();
        stockConfition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, roomAvailInsideParamDto.getLhotelGroupCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ, roomAvailInsideParamDto.getLhotelCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.isHalt.toString(), CriteriaUtil.Operator.EQ,"F"),
                new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.occDate.toString(), CriteriaUtil.Operator.GTE, DateUtil.parseDateWevFormat(roomAvailInsideParamDto.getArrtime())),
                new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.occDate.toString(), CriteriaUtil.Operator.LT, DateUtil.parseDateWevFormat(roomAvailInsideParamDto.getDeptime())),
                new ConditionDetail(GcRmtypeAvailSync.GcRmtypeAvailSync_.l2RRmtype.toString(), CriteriaUtil.Operator.IN,l2rRmtypes)

        });
        QueryResult<GcRmtypeAvailSync> rmtypeAvailkResult = commonService.findAllByCondition(GcRmtypeAvailSync.class, stockConfition);
        QueryResult<PmsRmtypeAvailDto> pmsRmtypeAvailDtoQueryResult=new QueryResult<>();
        pmsRmtypeAvailDtoQueryResult.setCurrentPage(rmtypeAvailkResult.getCurrentPage());
        pmsRmtypeAvailDtoQueryResult.setTotalrecord(rmtypeAvailkResult.getTotalrecord());
        if(rmtypeAvailkResult.getResultlist()!=null){
            List<PmsRmtypeAvailDto> pmsRmtypeAvailDtos=new ArrayList<>();
            PmsRmtypeAvailDto pmsRmtypeAvailDto;
            for(GcRmtypeAvailSync gcRmtypeAvailSync:rmtypeAvailkResult.getResultlist()){
                pmsRmtypeAvailDto=ClassConverUtil.copyPropertiesToDto(gcRmtypeAvailSync,PmsRmtypeAvailDto.class,false);
                pmsRmtypeAvailDto.setRsvDate(gcRmtypeAvailSync.getOccDate());
                pmsRmtypeAvailDto.datetimeToString();
                pmsRmtypeAvailDtos.add(pmsRmtypeAvailDto);
            }
            pmsRmtypeAvailDtoQueryResult.setResultlist(pmsRmtypeAvailDtos);
        }
        return pmsRmtypeAvailDtoQueryResult;
    }
}
